#include "DlgBondDealMatrix.h"

#include "../StringResource.h"
// #include <core/StyleMgr.h>
// #include <core/ImageMgr.h>
#include <core/FileSys.h>
#include <datareceiver/PanoramicDealReceiver.h>
#include <qbbond/BondDealMatrix/BondDealMatrix.h>
#include <qbfixedincome/BondDealMatrix/BondDealMatrixSettingDlg.h>
#include <uam/UserAccountManager.h>
#include <widgets/STabCtrl.h>

#include <QHBoxLayout>
#include <QSettings>
#include <QVBoxLayout>

const int kLineHeight = 24;

DlgBondDealMatrix::DlgBondDealMatrix(QWidget* p) : SDialog(p) {
  setMinimumWidth(644);
  setTitle(NewStringTable::strBondDealMatrix());
  setEnableSetting(true);

  QVBoxLayout* layout = qobject_cast<QVBoxLayout*>(this->layout());
  if (!layout) return;

  layout->setContentsMargins(4, 0, 4, 4);

  QHBoxLayout* tabLayout = new QHBoxLayout();
  tabLayout->setSpacing(4);
  m_tabViewType = new STabCtrl(this);
  m_tabViewType->addTab(NewStringTable::strFixedIncomeViewType(0));  // 列
  m_tabViewType->addTab(NewStringTable::strFixedIncomeViewType(1));  // 图
  m_tabViewType->setTabDisabled(1);
  m_tabViewType->selectTab(VIEW_LIST);
  m_tabViewType->setFixedSize(48, 24);
  tabLayout->addWidget(m_tabViewType);

  m_tabBondType = new STabCtrl(this);
  m_tabBondType->setFixedHeight(24);
  m_tabBondType->addTab(NewStringTable::strBondDealMatrixTab(0));
  m_tabBondType->addTab(NewStringTable::strBondDealMatrixTab(1));
  m_tabBondType->addTab(NewStringTable::strBondDealMatrixTab(2));
  m_tabBondType->addTab(NewStringTable::strBondDealMatrixTab(3));
  m_tabBondType->selectTab(BOND_GOV);
  m_bondType = (int)BOND_GOV;
  tabLayout->addWidget(m_tabBondType);

  layout->addLayout(tabLayout);
  layout->addSpacing(4);

  m_matrix = new BondDealMatrix(this);
  m_matrix->setMatrixType(BondDealMatrix::eMTFixedIncomeGov);
  m_matrix->setMatrixData(&m_data);
  int nDiff = CBondDealTermRange::instance().GetDiffType(
      (CBondDealTermRange::emBondType)m_bondType);
  m_matrix->setDiffCDC(nDiff);
  layout->addWidget(m_matrix);

  m_chart = new BondDealChart(this);
  m_chart->createChart();
  m_chart->setType(BondDealChart::type_gov);
  m_chart->hide();
  layout->addWidget(m_chart);

  connect(m_tabBondType, &STabCtrl::tabSelected, this,
          &DlgBondDealMatrix::onBondTypeChange);
  connect(m_tabViewType, &STabCtrl::tabSelected, this,
          &DlgBondDealMatrix::onViewTypeChange);
  connect(&PanoramicDealReceiver::instance(),
          &PanoramicDealReceiver::dealMarketPush, this,
          &DlgBondDealMatrix::onDealMarketPush);
  connect(&PanoramicDealReceiver::instance(),
          &PanoramicDealReceiver::dealMarketArrived, this,
          &DlgBondDealMatrix::onDealMarketArrived);
  connect(&PanoramicDealReceiver::instance(),
          &PanoramicDealReceiver::termRangeArrived, this,
          &DlgBondDealMatrix::onDealMarketArrived);
  connect(m_title, &SDialogTitle::setting, this,
          &DlgBondDealMatrix::onSettingClick);
  connect(this, &DlgBondDealMatrix::notifyReloadData, m_matrix,
          &BondDealMatrix::reloadData);
  connect(m_chart->dragBar(), &BaseChartDragBarElement::leftDrag, this,
          &DlgBondDealMatrix::onBondRateLeftDrag);
  connect(m_chart->dragBar(), &BaseChartDragBarElement::rightDrag, this,
          &DlgBondDealMatrix::onBondRateRightDrag);
  connect(m_chart->dragBar(), &BaseChartDragBarElement::centralDrag, this,
          &DlgBondDealMatrix::onBondRateCentralDrag);

  PanoramicDealReceiver::instance().requestTermRange();
  PanoramicDealReceiver::instance().requestPanoramicDeal(false);

  onDealMarketArrived();

  int v1 = 0, v2 = 0;
  loadMatrixConfig(v1, v2);
  m_data.setTextShowType(v1);
  m_data.setChartShowType(v2);
}

SDialog* DlgBondDealMatrix::clone(QWidget* parent) {
  return new DlgBondDealMatrix(parent);
}

void DlgBondDealMatrix::loadMatrixConfig(int& showTextType,
                                         int& showChartType) {
  QSettings settings(
      FileSys::instance()->writeableAppCfgDir() + "/gszhConfig.ini",
      QSettings::IniFormat);

  settings.beginGroup("matrix");
  showTextType = settings.value("text", 0).toInt();
  showChartType = settings.value("chart", 0).toInt();
  settings.endGroup();
}

void DlgBondDealMatrix::refreshUI() {}

void DlgBondDealMatrix::onDealMarketPush(
    int funcId, QList<xQBPanoramicMarketStreamUnit> lstData) {
  if (m_matrix) {
    std::map<int, int> mapCell;
    if (m_data.updateBondData(lstData, mapCell)) {
      m_matrix->updateCell(mapCell);
    }
  }
}

void DlgBondDealMatrix::onDealMarketArrived() {
  m_data.reloadBondData();
  if (m_matrix) m_matrix->reloadData();
  // refreshUI();
}

void DlgBondDealMatrix::onBondTypeChange(int index) {
  int nDiff = CBondDealTermRange::instance().GetDiffType(
      (CBondDealTermRange::emBondType)index);
  switch (index) {
    case 0:
      m_matrix->setDiffCDC(nDiff);
      m_matrix->setMatrixType(BondDealMatrix::eMTFixedIncomeGov);
      m_bondType = index;
      setEnableSetting(true);
      break;
    case 1:
      m_matrix->setDiffCDC(nDiff);
      m_matrix->setMatrixType(BondDealMatrix::eMTFixedIncomeCredit);
      m_bondType = index;
      setEnableSetting(true);
      break;
    case 2:
      m_matrix->setDiffCDC(nDiff);
      m_matrix->setMatrixType(BondDealMatrix::eMTFixedIncomeNCDPrimary);
      m_bondType = index;
      setEnableSetting(false);
      break;
    case 3:
      m_matrix->setDiffCDC(nDiff);
      m_matrix->setMatrixType(BondDealMatrix::eMTFixedIncomeNCD);
      m_bondType = index;
      setEnableSetting(true);
      break;
    default:
      break;
  }
}

void DlgBondDealMatrix::onViewTypeChange(int index) {
  QVBoxLayout* layout = qobject_cast<QVBoxLayout*>(this->layout());
  if (!layout) return;
  if (index == 0) {
    if (m_chart) m_chart->hide();
    if (m_matrix) m_matrix->show();
    // 		for (int i = layout->count() - 1; i >= 0; --i)
    // 		{
    // 			QLayoutItem* layoutItem = layout->itemAt(i);
    // 			if (layoutItem->spacerItem())
    // 			{
    // 				layout->removeItem(layoutItem);
    // 				break;
    // 			}
    // 		}
  } else {
    if (m_matrix) m_matrix->hide();
    if (m_chart) m_chart->show();
    //		layout->addStretch();
  }
}

void DlgBondDealMatrix::onSettingClick() {
  xQBBondDealTermRgReq req;
  SSUserAccountManager& uam = SSUserAccountManager::instance();
  FIELDCOPY(req.m_UserId, uam.GetUserInfo().m_UserId);
  FIELDCOPY(req.m_UserAccount, uam.GetUserAccount());
  CBondDealTermRange& range = CBondDealTermRange::instance();
  for (auto itRange : std::vector<int>{CBondDealTermRange::bondType_Interest,
                                       CBondDealTermRange::bondType_Credit,
                                       CBondDealTermRange::bondType_NCDPrimary,
                                       CBondDealTermRange::bondType_NCD}) {
    sBondDealTermList unitMatrix;

    unitMatrix.m_nRate = (int)itRange;
    int nColCount = 0;
    if (itRange == CBondDealTermRange::bondType_Interest)
      nColCount = CBondDealTermRange::termRg_Interest;
    else if (itRange == CBondDealTermRange::bondType_Credit)
      nColCount = CBondDealTermRange::termRg_Credit;
    else if (itRange == CBondDealTermRange::bondType_NCDPrimary)
      nColCount = CBondDealTermRange::termRg_NCDPrimary;
    else if (itRange == CBondDealTermRange::bondType_NCD)
      nColCount = CBondDealTermRange::termRg_NCD;
    for (int nL = 1; nL < nColCount; nL++) {
      sBondDealTermRgUnit unitTerm;
      if (itRange == CBondDealTermRange::bondType_Interest) {
        FIELDCOPY(unitTerm.m_term, strInterestRange[nL].c_str());
        unitTerm.m_nCol = nL;
      } else if (itRange == CBondDealTermRange::bondType_Credit) {
        FIELDCOPY(unitTerm.m_term, strCreditRange[nL].c_str());
        unitTerm.m_nCol = nL;
      } else if (itRange == CBondDealTermRange::bondType_NCDPrimary) {
        FIELDCOPY(unitTerm.m_term, strNCDPrimaryRange[nL].c_str());
        unitTerm.m_nCol = nL;
      } else if (itRange == CBondDealTermRange::bondType_NCD) {
        FIELDCOPY(unitTerm.m_term, strNCDRange[nL].c_str());
        unitTerm.m_nCol = nL;
      }
      if (range.GetRange(
              unitTerm, static_cast<CBondDealTermRange::emBondType>(itRange))) {
        std::string strRangeLeft = unitTerm.m_rangeLeft;
        std::string strRangeRight = unitTerm.m_rangeRight;
        char sEndLeft{0}, sEndRight{0};
        if (strRangeLeft.length() != 0) {
          sEndLeft = strRangeLeft[strRangeLeft.length() - 1];
        }
        if (strRangeRight.length() != 0) {
          sEndRight = strRangeRight[strRangeRight.length() - 1];
        }
        if ((sEndLeft != 'M' && sEndLeft != 'Y') ||
            (sEndRight != 'M' && sEndRight != 'Y')) {
          range.InitDefaultRange(
              unitTerm, static_cast<CBondDealTermRange::emBondType>(itRange));
        }
        unitMatrix.m_listTerm.push_back(unitTerm);
      }
      unitMatrix.m_diffType = range.GetDiffType(
          static_cast<CBondDealTermRange::emBondType>(itRange));
    }
    req.m_matrixTerm.push_back(unitMatrix);
  }

  loadMatrixConfig(req.m_TextShowType, req.m_ChartShowType);

  BondDealMatrixSettingDlg dlg(this, m_bondType, &req,
                               BondDealMatrixSettingDlg::emParent_FixedIncome);

  connect(&dlg, &BondDealMatrixSettingDlg::notifyMatrixTermChanged, this,
          [=](int type) { m_matrix->updateMatrix(type); });

  int ret = dlg.exec();

  if (ret == QDialog::Accepted && !req.m_matrixTerm.empty()) {
    qb::SSRequestMsg msg;
    memset(&msg, 0, sizeof(qb::SSRequestMsg));
    msg.m_pRequest = (void*)&req;
    msg.m_FuncID = E_FID_QB_DEAL_TERM_RANGE_OVERALL_MODIFY;
    MessagePoster poster(&msg, qbmsg::panoramic::EncodeFunc);
    poster.send(this);
  }

  if (m_data.textShowType() != req.m_TextShowType ||
      m_data.chartShowType() != req.m_ChartShowType) {
    m_data.saveTextAndChartType(req.m_TextShowType, req.m_ChartShowType);
    // m_data.reloadBondData();
    if (m_matrix) m_matrix->reloadData();
  }
}

void DlgBondDealMatrix::onBondRateLeftDrag(double ratio) {
  QB_CHECK_RETURN_VOID1(m_chart);

  m_chart->setLeftDrag(ratio);
  // 	onBondRateChanged();
}

void DlgBondDealMatrix::onBondRateRightDrag(double ratio) {
  QB_CHECK_RETURN_VOID1(m_chart);

  m_chart->setRightDrag(ratio);
  // 	onBondRateChanged();
}

void DlgBondDealMatrix::onBondRateCentralDrag(double ratio1, double ratio2) {
  QB_CHECK_RETURN_VOID1(m_chart);

  m_chart->setCentralDrag(ratio1, ratio2);
  // 	onBondRateChanged();
}

// void DlgBondDealMatrix::onBondRateChanged()
// {
// 	QB_CHECK_RETURN_VOID1(m_chart);
//
// 	m_chart->loadData(BondDetailCache::instance().getChart(m_data->bond().GetCombBondKey()).m_pYieldCurve,
// m_data->bond().GetRemainedDays(ServerTimeMgr::instance().serverTime()));
// }

void DlgBondDealMatrix::onDataArrived(const qb::SSAckMsg& msg) {
  if (!msg.m_pRet) return;
  int funcId = msg.m_FuncID;
  if (E_FID_QB_DEAL_TERM_RANGE_OVERALL_MODIFY == funcId) {
    xQBBondDealTermRgAck* pdata = (xQBBondDealTermRgAck*)msg.m_pRet;
    if (!pdata) return;

    CBondDealTermRange::instance().UpdateRange(pdata, false);
    int nDiff = CBondDealTermRange::instance().GetDiffType(
        (CBondDealTermRange::emBondType)m_bondType);
    m_matrix->setDiffCDC(nDiff);
    emit notifyReloadData();
  }
}
